package com.jinxin.platform.cddjnhjcxtsysset.redis;

import com.alibaba.fastjson.JSON;
import com.jinxin.platform.cddjnhjcxtsysset.common.Constant;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * All rights Reserved, Designed By www.beonelot.com
 *
 * @author: 金鑫智慧
 * @version: V1.0
 * @Copyright: www.beonelot.com Inc. All rights reserved.
 * 注意：本内容仅限于重庆金鑫智慧科技有限公司内部传阅，禁止外泄以及用于其他的商业目的
 * @Date: 2019/6/13
 * @Author: yangjie
 **/
@Service
public class RedisUtil {
    @Autowired
    private RedisTemplate redisTemplate ;

    private static final Logger logger = LoggerFactory.getLogger(RedisUtil.class);

    /**
     * 获取递增的序列号
     *
     * @param prefix 生成序列号的前缀
     * @return
     */
    public long getIncre(String prefix) {
        //序列号前缀加特定标识，如系统模块名之类的 防止重复
        String key = Constant.MODULE_KEY+"_" + prefix;
        long increResult;
        try {
            //如果该key不存在 会自动创建，值为第二个参数delta
            //最终调用的还是jedis的incrBy(byte[] key, long value)方法
            increResult = redisTemplate.opsForValue().increment(key, 1);
            //不足补位
        } catch (Exception e) {
            logger.info("获取序列号失败");
            /*这里可以根据需求手动生成一个不重复的单号，
             * */
            return 0;
        }
        return increResult;
    }
    public boolean set(final String key, Object value) {
        boolean result = false;
        try {
            ValueOperations<Serializable, Object> operations = redisTemplate.opsForValue();
            operations.set(key, value);
            result = true;
        } catch (Exception e) {
            logger.error("error",e);
        }
        return result;
    }

    /**
     * 写入缓存设置时效时间
     */
    public boolean set(final String key, Object value, Long expireTime) {
        try {
            redisTemplate.opsForValue().set(key, value, expireTime, TimeUnit.SECONDS);
            return true;
        } catch (Exception e) {
            logger.error("error",e);
            return false;
        }
    }

    /**
     * 读取缓存
     */
    public Object get(final String key) {
        ValueOperations<String, Integer> operations = redisTemplate.opsForValue();
        return operations.get(key);
    }

    public List<Object> getByPrefix(final String prefix){
        Set<String> keys = redisTemplate.keys(prefix);
        List<Object> list = redisTemplate.opsForValue().multiGet(keys);
        return list;
    }

    public boolean hasKey(final String key) {
        return redisTemplate.hasKey(key);
    }

    /**
     * 获取key 的散列值
     * @param key			key键
     * @param field			散列
     * @return				散列值
     */
    public String hget(String key, String field) {
        try {
            return String.valueOf(redisTemplate.opsForHash().get(key, field));
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
        return null;
    }



    /**
     * 赋值 key的散列及值
     * @param key			key键
     * @param field			散列
     * @param value			内容
     * @return				0：已存在并被更新 1：赋值成功 -1 标识出错
     */
    public void hset(String key, String field, String value)  {
        try {
            redisTemplate.opsForHash().put(key, field, value);
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
    }

    /**
     * 赋值 key的散列及值（泛型）
     * @param key			key键
     * @param field			散列
     * @param value			泛型对象
     * @return				0：已存在并被更新 1：赋值成功 -1 标识出错
     */
    public  <T> void hset(String key, String field, T value)  {
        hset(key, field, JSON.toJSONString(value));
    }

    /**
     * 获取 HashMap 散列一个或多个值
     * @param key            key键
     * @param fields        一个或多个散列
     * @return				散列的值
     */
    public  List<Object> hmget(String key, List<Object> fields)  {
        try {
            return redisTemplate.opsForHash().multiGet(key, fields);
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
        return null;
    }
    /**
     * 存储 HashMap
     * @param key			key键
     * @param hash			hash对象
     * @return				标识 OK:成功
     */
    public void hmset(String key, Map<String, String> hash)  {
        try {
            redisTemplate.opsForHash().putAll(key, hash);
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
    }

    /**
     * 获取 hash 散列数量
     * @param key			key键
     * @return				key 散列数量
     */
    public long hlen(String key)  {
        try {
            Long result = redisTemplate.opsForHash().size(key);
            return result == null ? 0 : result.longValue();
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
        return 0;
    }

    /**
     * 删除 hash 散列
     * @param key			key键
     * @param fields		散列
     * @return				成功删除数量
     */
    public  void hdel(String key, String[] fields)   {
        try {
            redisTemplate.opsForHash().delete(key, (Object[])fields);
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
    }

    /**
     * 获取hash散列的所有field
     * @param key			key键
     * @return				成功删除数量
     */
    public Set<Object> hkeys(String key)   {
        try {
            return redisTemplate.opsForHash().keys(key);
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
        return null;
    }

    /**
     * 获取hash散列的所有field
     * @param key            key键
     * @return				成功删除数量
     */
    public  List<Object> hvals(String key)   {
        try {
            return redisTemplate.opsForHash().values(key);
        } catch (DataAccessException e) {
            logger.error("error",e);
        }
        return null;
    }

   public void delete(){
       redisTemplate.delete(redisTemplate.keys("game"+"*"));
   }
   public void deleteOne(String account){
       redisTemplate.delete(redisTemplate.keys("game"+account+"*"));
   }
}
